package com.hjh.core.framework

import com.elvishew.xlog.printer.file.naming.FileNameGenerator
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream


/**
 * @author： hjh
 * @createDate： 2025/5/19 10:35
 * @description： XLog 日志文件命名
 * @qq： 3472903821
 * @version: 1.0
 */
class BaseXLogFileNameGenerator(private val prefix: String = "") : FileNameGenerator {

    private val dateFormatThreadLocal = ThreadLocal.withInitial {
        SimpleDateFormat("yyyy-MM-dd", Locale.CHINA).apply {
            timeZone = TimeZone.getDefault()
        }
    }

    override fun isFileNameChangeable(): Boolean = true

    override fun generateFileName(logLevel: Int, timestamp: Long): String {
        val sdf = dateFormatThreadLocal.get()
        val formattedDate = sdf?.format(Date(timestamp))
        return if (prefix.isNotBlank()) "$prefix-$formattedDate.log" else "$formattedDate.log"
    }
}

@Suppress("unused")
object XLogUtil {

    @Throws(IOException::class)
    fun compress(folderPath: String?, zipFilePath: String?) {
        if (folderPath == null) return
        if (zipFilePath == null) return

        val sourceDir = File(folderPath)
        if (!sourceDir.exists() || !sourceDir.isDirectory) {
            throw IOException("Folder $folderPath doesn't exist or isn't a directory")
        }

        val zipFile = File(zipFilePath)
        val zipParent = zipFile.parentFile
        if (zipParent != null && !zipParent.exists() && !zipParent.mkdirs()) {
            throw IOException("Failed to create parent directory for zip file: " + zipParent.absolutePath)
        }

        FileOutputStream(zipFile).use { fos ->
            BufferedOutputStream(fos).use { bos ->
                ZipOutputStream(bos).use { zos ->
                    zipDirectoryRecursive(zos, sourceDir, sourceDir.absolutePath)
                }
            }
        }
    }

    @Throws(IOException::class)
    private fun zipDirectoryRecursive(zos: ZipOutputStream, fileToZip: File, basePath: String?) {
        if (fileToZip.isHidden) return

        var relativePath = if (basePath == null)
            fileToZip.name
        else
            fileToZip.absolutePath.substring(basePath.length + 1).replace("\\", "/")

        if (fileToZip.isDirectory) {
            if (relativePath.isNotEmpty()) {
                if (!relativePath.endsWith("/")) {
                    relativePath += "/"
                }
                zos.putNextEntry(ZipEntry(relativePath))
                zos.closeEntry()
            }

            val children = fileToZip.listFiles()
            if (children != null) {
                for (child in children) {
                    zipDirectoryRecursive(zos, child, basePath)
                }
            }
        } else {
            FileInputStream(fileToZip).use { fis ->
                BufferedInputStream(fis).use { bis ->
                    val zipEntry = ZipEntry(relativePath)
                    zos.putNextEntry(zipEntry)

                    val buffer = ByteArray(8192)
                    var len: Int
                    while ((bis.read(buffer).also { len = it }) != -1) {
                        zos.write(buffer, 0, len)
                    }
                    zos.closeEntry()
                }
            }
        }
    }
}